package script

import (
	"ScadaDaemon/common"
	"log"
	"os/exec"
	"runtime"
	"strings"
	"syscall"
)

func ExeCommand(infos []common.AppInfo) {

	for _, app := range infos {
		appName := app.AppName
		script := app.StartScript
		resCode, err := doExeCommand(appName)

		if err != nil {
			log.Printf("运行命令：%s 出错，错误信息：%v\n", appName, err)
			continue
		}
		if resCode == 0 {
			//log.Printf("程序：%s 运行正常，", appName)
			continue
		}
		log.Printf("程序：%s挂了", appName)
		log.Printf("开始执行：%s 重启程序", script)
		resCode, err = doExeCommand(script)
		if err != nil {
			log.Printf("运行命令：%s 重启程序出错，错误信息：%v\n", script, err)
			continue
		}
		if resCode == 0 {
			log.Printf("运行命令：%s 重启程序成功，", script)
		} else {
			log.Printf("运行命令：%s 重启程序失败，", script)
		}
	}

}

func doExeCommand(name string) (resCode int, err error) {
	// 延迟处理的函数
	defer func() {
		// 发生宕机时，获取panic传递的上下文并打印
		err := recover()
		switch err.(type) {
		case runtime.Error: // 运行时错误
			log.Printf("监视服务出现运行时错误错误：%v\n", err)
		default: // 非运行时错误
			log.Printf("监视服务出现非运行时错误错误：%v\n", err)
		}
	}()
	cmd := exec.Command("/bin/bash", "-c", name)
	stdout, _ := cmd.StdoutPipe() //创建输出管道
	defer stdout.Close()
	if err := cmd.Start(); err != nil {
		log.Printf("cmd.Start: %v", err)
		log.Printf("运行命令222：%v\n", name)
		log.Printf("监视服务出现错误11：%v\n", err)
	}
	//log.Println("当前执行命令")
	//log.Println(cmd.Args)     //查看当前执行命令
	//cmdPid := cmd.Process.Pid //查看命令pid
	//log.Println("查看当前执行命令的pid")
	//log.Println(cmdPid)
	if !strings.Contains(name, "nohup") {
		//log.Println("当前命令不高含 nohup ")
		//result, _ := ioutil.ReadAll(stdout) // 读取输出结果
		//resdata := string(result)
		//log.Println("查看当前执行命令的输出结果")
		//log.Println(resdata)
		var res int
		if err := cmd.Wait(); err != nil {
			if ex, ok := err.(*exec.ExitError); ok {
				log.Println("cmd exit status")
				res = ex.Sys().(syscall.WaitStatus).ExitStatus() //获取命令执行返回状态，相当于shell: echo $?
			}
		}
		//log.Printf("The 程序输出 is ")
		//log.Println("-----------------")
		//log.Println(res)
		//log.Println("-----------------")
		return res, err
	} else {
		return 0, nil
	}

}
